// Copyright (c) 1996-2002 John Lyon-Smith. All rights reserved.

#pragma once

namespace wxtl
{
	class CriticalSection
	{
	public:
		CriticalSection(DWORD dwSpinCount = 0)
		{
		#if _WIN32_WINDOWS >= 0x0410 && _WIN32_WINNT >= 0x0403
			InitializeCriticalSectionAndSpinCount(&m_cs, dwSpinCount);
		#else
			(void)dwSpinCount;
			InitializeCriticalSection(&m_cs);
		#endif
		}

		virtual ~CriticalSection()
		{
			DeleteCriticalSection(&m_cs);
		}

		void enter()
		{
			EnterCriticalSection(&m_cs);
		}

		#if _WIN32_WINDOWS >= 0x0400 && _WIN32_WINNT >= 0x0403
		bool tryEnter()
		{
			return TryEnterCriticalSection(&m_cs) == TRUE;
		}
		#endif

		void leave()
		{
			LeaveCriticalSection(&m_cs);
		}

		class Auto
		{
		public:
			Auto(CriticalSection& cs) { m_pcs = &cs; m_pcs->enter(); }
			~Auto() { m_pcs->leave(); }
		protected:
			CriticalSection *m_pcs;
		};
		
	protected:
		CRITICAL_SECTION m_cs;
	};
}
